package com.zjl.SpringBoot.第06章_基本特性;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;

/**
 * 作用：具有环境隔离能力，快速切换开发、测试、生产环境
 * 步骤:
 *      1.标识环境:指定哪些组件、配置在哪个生效
 *      2.切换环境:这个环境对应的所有组件和配置就应该生效
 *
 * 指定环境
 *      Spring Profiles 提供一种隔离配置的方式，使其仅在特定环境生效
 *      容器中的组件（包含配置类）都可以被 @Profile 标记，来指定在什么环境下被加载
 *      不标注 表示 任何时候都生效
 *
 * 配置文件：
 *      spring.profiles.active=制定环境1,制定环境2
 * main函数里
 *      System.setProperty("spring.profiles.active","制定环境1,制定环境2");
 * 命令行
 *      java -jar  --spring.profiles.active=制定环境1,制定环境2
 *
 *最佳实战
 * 生效的环境 = 激活的环境/默认环境 + 包含的环境
 *      项目里面这么用
 *              基础的配置【mybatis、log】写到包含环境中
 *              需要动态切换的配置【 db、redis】写到激活的环境中
 *
 * #指定激活指定环境
 * # application-制定环境.properties   application-制定环境.yml
 * spring.profiles.active=制定环境
 *
 * #包含制定环境，不管你激活那个环境，我都生效
 * spring.profiles.include=总是要生效的环境
 * spring.profiles.include[0]=总是要生效的环境
 *
 * #指定默认环境  不推荐
 * #spring.profiles.default=test
 *
 * #分组，
 * spring.profiles.group.组1=dev,uat
 *
 * spring.profiles.group.组2=dev,default
 * #效果等于 上面的
 * spring.profiles.group.组2[0]=dev
 * spring.profiles.group.组2[1]=default
 *
 */
@SpringBootApplication(
        exclude = {DataSourceAutoConfiguration.class}
)
public class C_Profiles环境隔离 {
    public static void main(String[] args) {
//        System.setProperty("spring.profiles.active","text");
        ConfigurableApplicationContext run = SpringApplication.run(C_Profiles环境隔离.class, args);

        try {
            Object zhangJiaoLong = run.getBean("zhangJiaoLong");
            System.out.println(zhangJiaoLong);
        }catch (Exception e){
            System.err.println(e.getMessage());
        }

        try {
            Object cat = run.getBean("cat");
            System.out.println(cat);
        }catch (Exception e){
            System.err.println(e.getMessage());
        }
        try {
            Object dog1 = run.getBean(Dog.class);//没在制定环境直接报错   No qualifying bean of type 'com.zjl.SpringBoot.第06章_基本特性.Dog' available
            System.out.println(dog1);
        }catch (Exception e){
            System.err.println(e.getMessage());
        }
        try {
            Object pig = run.getBean("pig");
            System.out.println(pig);
        }catch (Exception e){
            System.err.println(e.getMessage());
        }
        try {
            Object xxx = run.getBean("xxx");
            System.out.println(xxx);
        }catch (Exception e){
            System.err.println(e.getMessage());
        }
        try {
            Object xxx = run.getBean("xxx");
            System.out.println(xxx);
        }catch (Exception e){
            System.err.println(e.getMessage());
        }
        System.err.println("***********启动完毕**当前编码:" + Charset.defaultCharset().name() + "****************");
    }
}
@Profile(value = {"text","dev"})//只能在  text、dev 能生效   其他不生效,默认也不生效
@Component
class Cat{

}
@Profile({"test"})
@Component
class Dog {

}
@Profile({"dev"})
@Component
class Pig {

}
@Profile({"default"})//只能在  默认生效
@Component
class ZhangJiaoLong {

}
@Profile({"dev"})//只能在 制定环境生效
@Configuration
class MyProfileConfig {

    @Profile({"uat"})//只能在  制定环境生效   而且也受此类的 @Profile 影响
    @Bean
    public Xxx xxx(){
        return new Xxx();
    }

}
class Xxx {}